using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

using Tao.OpenGl;

namespace tp3
{
    public class Perfil
    {
        private static double diferenciaCilindro = 0.9d;
        private static double diferenciaPlano = 0.1d;

        public static void DibujarPerfilCilindrico(List<Punto> puntos, int desde, int hasta)
        {
            Gl.glEnable(Gl.GL_LIGHTING);

            float[] materialColor = ColorTP.FColor(Color.Firebrick);
            float[] materialSpecular = { 1.0f, 1.0f, 1.0f, 1.0f };
            float[] materialEmission = { 0.05f, 0.05f, 0.05f, 1.0f };

            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE, materialColor);
            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, materialSpecular);
            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, materialEmission);
            Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, 25);

            Circulo.Radio = 1;

            List<List<Punto>> puntosCirculoAnterior = new List<List<Punto>>();
            List<List<Punto>> puntosCirculoNuevo = new List<List<Punto>>();

            int j = 1;
            int anteriorInicial;
            if (desde == 0)
            {
                anteriorInicial = puntos.Count;
            }
            else
            {
                anteriorInicial = desde;
            }

            while (puntosCirculoNuevo.Count == 0)
            {
                puntosCirculoNuevo = Circulo.CalcularPuntos(new Punto(puntos[anteriorInicial - j].X,
                    puntos[anteriorInicial - j].Y,
                    puntos[anteriorInicial - j].Z + diferenciaCilindro),
                    new Punto(puntos[desde].X, puntos[desde].Y, puntos[desde].Z + diferenciaCilindro));
                j++;
            }

            for (int i = desde+1; i <= hasta; i++)
            {

                if (puntosCirculoNuevo.Count != 0)
                {
                    puntosCirculoAnterior = puntosCirculoNuevo;
                }

                puntosCirculoNuevo = Circulo.CalcularPuntos(new Punto(puntos[i - 1].X,
                puntos[i - 1].Y,
                puntos[i - 1].Z + diferenciaCilindro),
                new Punto(puntos[i].X, puntos[i].Y, puntos[i].Z + diferenciaCilindro));

                if (puntosCirculoNuevo.Count == 0)
                    continue;

                Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                //Gl.glBegin(Gl.GL_LINE_STRIP);

                for (int p = 0; p < puntosCirculoNuevo[1].Count; p++)
                {
                    Gl.glNormal3d(puntosCirculoAnterior[0][p].X,
                        puntosCirculoAnterior[0][p].Y,
                        puntosCirculoAnterior[0][p].Z);
                    Gl.glVertex3d(puntosCirculoAnterior[1][p].X,
                        puntosCirculoAnterior[1][p].Y,
                        puntosCirculoAnterior[1][p].Z);

                    Gl.glNormal3d(puntosCirculoNuevo[0][p].X,
                        puntosCirculoNuevo[0][p].Y,
                        puntosCirculoNuevo[0][p].Z);
                    Gl.glVertex3d(puntosCirculoNuevo[1][p].X,
                        puntosCirculoNuevo[1][p].Y,
                        puntosCirculoNuevo[1][p].Z);
                }


                Gl.glNormal3d(puntosCirculoAnterior[0][0].X,
                        puntosCirculoAnterior[0][0].Y,
                        puntosCirculoAnterior[0][0].Z);
                Gl.glVertex3d(puntosCirculoAnterior[1][0].X,
                    puntosCirculoAnterior[1][0].Y,
                    puntosCirculoAnterior[1][0].Z);

                Gl.glNormal3d(puntosCirculoNuevo[0][0].X,
                    puntosCirculoNuevo[0][0].Y,
                    puntosCirculoNuevo[0][0].Z);
                Gl.glVertex3d(puntosCirculoNuevo[1][0].X,
                    puntosCirculoNuevo[1][0].Y,
                    puntosCirculoNuevo[1][0].Z);

                Gl.glEnd();
            }
        }


        public static void DibujarPerfilPlano(List<Punto> puntos, int desde, int hasta)
        {
            Gl.glEnable(Gl.GL_LIGHTING);

            float[] materialColor = ColorTP.FColor(Color.CadetBlue);
            float[] materialSpecular = { 1.0f, 1.0f, 1.0f, 1.0f };
            float[] materialEmission = { 0.05f, 0.05f, 0.05f, 1.0f };

            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE, materialColor);
            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, materialSpecular);
            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, materialEmission);
            Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, 25);

            
            List<List<Punto>> puntosPlanoAnterior = new List<List<Punto>>();
            List<List<Punto>> puntosPlanoNuevo = new List<List<Punto>>();

            int j = 1;
            int anteriorInicial;
            if (desde == 0)
            {
                anteriorInicial = puntos.Count;
            }
            else
            {
                anteriorInicial = desde;
            }

            while (puntosPlanoNuevo.Count == 0)
            {
                puntosPlanoNuevo = Plano.CalcularPuntos(new Punto(puntos[anteriorInicial - j].X,
                    puntos[anteriorInicial - j].Y,
                    puntos[anteriorInicial - j].Z - diferenciaPlano),
                    new Punto(puntos[desde].X, puntos[desde].Y, puntos[desde].Z - diferenciaPlano));
                j++;
            }

            for (int i = desde + 1; i <= hasta; i++)
            {

                if (puntosPlanoNuevo.Count != 0)
                {
                    puntosPlanoAnterior = puntosPlanoNuevo;
                }

                puntosPlanoNuevo = Plano.CalcularPuntos(new Punto(puntos[i - 1].X,
                puntos[i - 1].Y,
                puntos[i - 1].Z - diferenciaPlano),
                new Punto(puntos[i].X, puntos[i].Y, puntos[i].Z - diferenciaPlano));

                if (puntosPlanoNuevo.Count == 0)
                    continue;

                Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                //Gl.glBegin(Gl.GL_LINE_STRIP);

                for (int p = 0; p < puntosPlanoNuevo[1].Count; p++)
                {
                    Gl.glNormal3d(puntosPlanoAnterior[0][p].X,
                        puntosPlanoAnterior[0][p].Y,
                        puntosPlanoAnterior[0][p].Z);
                    Gl.glVertex3d(puntosPlanoAnterior[1][p].X,
                        puntosPlanoAnterior[1][p].Y,
                        puntosPlanoAnterior[1][p].Z);

                    Gl.glNormal3d(puntosPlanoNuevo[0][p].X,
                        puntosPlanoNuevo[0][p].Y,
                        puntosPlanoNuevo[0][p].Z);
                    Gl.glVertex3d(puntosPlanoNuevo[1][p].X,
                        puntosPlanoNuevo[1][p].Y,
                        puntosPlanoNuevo[1][p].Z);
                }

                Gl.glEnd();
            }
        }
    }
}
